﻿using JinianNet.JNTemplate.Runtime;
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using My.Admin.Dto.System;
using My.Admin.Enum;
using My.Admin.Model.System;
using My.Admin.Service.System;
using My.Admin.Service.System.IService;
using My.Admin.Util;
using My.Core.Attributes;
using My.Core.Cache;
using My.Core.CustomException;
using My.Core.DynamicWebApi.Attributes;
using My.Core.Enums;
using My.Core.Extensions;
using My.Core.Options;
using My.Core.Util;
using My.Framework;
using NewLife.Caching;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Yitter.IdGenerator;

namespace My.Admin.Dynamic
{
	[Service("SysAuthController")]
	public class SysAuthController
	{
		private readonly UserManager _userManager;
		private readonly ISysUserService _sysUserRep;
		private readonly IHttpContextAccessor _httpContextAccessor;
		private readonly ICaptcha _captcha;
		private readonly JwtSettings _jwtSettings;

		public SysAuthController(UserManager userManager, IHttpContextAccessor httpContextAccessor, ISysUserService sysUserRep, ICaptcha captcha, IOptions<JwtSettings> jwtSettings)
		{
			_userManager = userManager;
			_sysUserRep = sysUserRep;
			_httpContextAccessor = httpContextAccessor;
			_captcha = captcha;
			_jwtSettings = jwtSettings.Value;
		}

		/// <summary>
		/// 用户登录
		/// </summary>
		/// <param name="name"></param>
		/// <param name="pass"></param>
		/// <returns></returns>
		[HttpPost]
		[Route("Login")] // 路由地址规则
		public async Task<LoginOutput> Login([Required] LoginInput input)
		{
			// 判断验证码
			if (!_captcha.Validate(input.CodeId.ToString(), input.Code))
				throw new CustomException(ResultCode.CAPTCHA_ERROR, "验证码错误", "验证码错误");

			// 账号是否存在
			var user = await _sysUserRep.AsQueryable().Filter(null, true).FirstAsync(u => u.Account.Equals(input.Account));
			_ = user ?? throw new CustomException(ResultCode.LOGIN_ERROR, "账号不存在", "账号不存在");

			//// 账号是否被冻结
			//if (user.Status == StatusEnum.Disable)
			//	throw Oops.Oh(ErrorCodeEnum.D1017);

			// 密码是否正确
			if (user.Password != MD5Encryption.Encrypt(input.Password, true, false))
				throw new CustomException(ResultCode.LOGIN_ERROR, "账号或密码错误", "账号或密码错误");

			return await CreateToken(user);
			//return JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings);
		}

		/// <summary>
		/// 用户登录
		/// </summary>
		/// <param name="name"></param>
		/// <param name="pass"></param>
		/// <returns></returns>
		[HttpGet]
		[Route("Login")] // 路由地址规则
		public async Task<LoginOutput> Login()
		{
			
			// 账号是否存在
			var user = await _sysUserRep.AsQueryable().Filter(null, true).FirstAsync(u => u.Account.Equals("wj"));
			_ = user ?? throw new CustomException(ResultCode.LOGIN_ERROR, "账号不存在", "账号不存在");

			//// 账号是否被冻结
			//if (user.Status == StatusEnum.Disable)
			//	throw Oops.Oh(ErrorCodeEnum.D1017);

			// 密码是否正确
			if (user.Password != MD5Encryption.Encrypt("111111", true, false))
				throw new CustomException(ResultCode.LOGIN_ERROR, "账号或密码错误", "账号或密码错误");

			return await CreateToken(user);
			//return JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings);
		}

		/// <summary>
		/// 获取验证码
		/// </summary>
		/// <returns></returns>
		[HttpGet]
		[Route("GetCaptcha")] // 路由地址规则
		[DisplayName("获取验证码")]
		public dynamic GetCaptcha()
		{
			var codeId = YitIdHelper.NextId().ToString();
			var captcha = _captcha.Generate(codeId);
			CacheHelper.SetCache(codeId, captcha.Code); // 将验证码保存到缓存中

			//_cache.Set(codeId, captcha.Code);

			string CacheCode = CacheHelper.Get(codeId) as string;
			return new { Id = codeId, Img = captcha.Base64 };
		}

		/// <summary>
		/// 获取登录账号
		/// </summary>
		/// <returns></returns>
		[HttpGet]
		[Route("GetUserInfo")] // 路由地址规则
		[DisplayName("获取登录账号")]
		[Authorize]
		public async Task<LoginUserOutput> GetUserInfo()
		{
			var user = await _sysUserRep.GetFirstAsync(u => u.Id == _userManager.UserId) ?? throw new CustomException(ResultCode.INVALID_REQUEST, "非法操作，未登录", "非法操作，未登录");
			//// 获取机构
			//var org = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysOrg>>().GetFirstAsync(u => u.Id == user.OrgId);
			//// 获取职位
			//var pos = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysPos>>().GetFirstAsync(u => u.Id == user.PosId);
			//// 获取拥有按钮权限集合
			//var buttons = await _sysMenuService.GetOwnBtnPermList();

			return new LoginUserOutput
			{
				Id = user.Id,
				Account = user.Account,
				RealName = user.RealName,
				Avatar = user.Avatar,
				Address = user.Address,
				Signature = user.Signature,
				OrgId = user.OrgId,
				//OrgName = org?.Name,
				//OrgType = org?.Type,
				//PosName = pos?.Name,
				//Buttons = buttons
			};
		}

		/// <summary>
		/// 退出系统
		/// </summary>
		[HttpGet]
		[Route("Logout")] // 路由地址规则
		[DisplayName("退出系统")]
		[Authorize]
		public void Logout()
		{
			if (string.IsNullOrWhiteSpace(_userManager.Account))
				throw new CustomException(ResultCode.INVALID_REQUEST, "非法操作，未登录", "非法操作，未登录");

			_httpContextAccessor.HttpContext.SignoutToSwagger();
		}

		/// <summary>
		/// 获取刷新Token
		/// </summary>
		/// <param name="accessToken"></param>
		/// <returns></returns>
		[HttpPost]
		[Route("GetRefreshToken")] // 路由地址规则
		[DisplayName("获取刷新Token")]
		[Authorize]
		public string GetRefreshToken([FromQuery] string accessToken)
		{
			var refreshTokenExpire = _jwtSettings.RefreshTokenTime;
			return JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);
		}

		/// <summary>
		/// 生成Token令牌
		/// </summary>
		/// <param name="user"></param>
		/// <returns></returns>
		[NonAction]
		public async Task<LoginOutput> CreateToken(SysUser user)
		{
			// 生成Token令牌
			//var accessToken1 = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(user), jwtSettings);

			var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
			{
				{ ClaimConst.UserId, user.Id },
				{ ClaimConst.TenantId, user.TenantId },
				{ ClaimConst.Account, user.Account },
				{ ClaimConst.RealName, user.RealName },
				//{ ClaimConst.AccountType, user.AccountType },
				{ ClaimConst.OrgId, user.OrgId },
				//{ ClaimConst.OrgName, user.SysOrg?.Name },
				//{ ClaimConst.OrgType, user.SysOrg?.Type },
			}, _jwtSettings.Expire);

			// 生成刷新Token令牌
			var refreshTokenExpire = _jwtSettings.RefreshTokenTime;
			var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, refreshTokenExpire);

			// 设置响应报文头
			_httpContextAccessor.HttpContext.SetTokensOfResponseHeaders(accessToken, refreshToken);

			// Swagger Knife4UI-AfterScript登录脚本
			// ke.global.setAllHeader('Authorization', 'Bearer ' + ke.response.headers['access-token']);

			return new LoginOutput
			{
				AccessToken = accessToken,
				RefreshToken = refreshToken
			};
		}
	}
}
